local handler = require "handler"
local util = require "util"
local reason = require "reason"
local error_code = require "error_code"
local constant = require "constant"
local cocall = require "cocall"
local game_def = require "game_def"
local utils = require "utils"

local table_insert = table.insert
local table_sort   = table.sort
local math_floor   = math.floor
local math_random  = math.random
local notify_money_changed = handler.notify_money_changed
local add_awards = handler.add_awards
local tostring = tostring

local BLACK_JOKER_NUMBER = 14
local RED_JOKER_NUMBER = 15

local award_handler = {}

function award_handler.REQ_BIND_PLAYER(msg)
    local ok,cur_index,code = R().mailsvr(1):call('.award_mgr','get_cur_index')
    if not ok or not cur_index then
        send_to_gateway('award.RSP_LUCKY_DRAW',{result = code or -1})
        return
    end

    local uid = player.uid
    local ok,bind_uid = R().basesvr({key=uid}):call('.msg_handler','get_bind_uid',uid)
    if not ok or not bind_uid then
        send_to_gateway('award.RSP_BIND_PLAYER',{result = -2})
        return
    end

    if bind_uid > 0 then
        send_to_gateway('award.RSP_BIND_PLAYER',{result = error_code.AWARD_HAS_BINDED})
        return
    end

    if msg.bind_uid == player.uid then --自己不能绑定自己
        send_to_gateway('award.RSP_BIND_PLAYER',{result = error_code.CANT_BIND_SELF})
        return
    end

    if msg.bind_uid ~= game_def.NEW_BIND_ACT_SYSTEM_UID then
        local ok,uid_info_map = R().friendsvr(1):call('.info_mgr','get_infos',{msg.bind_uid})
        print("REQ_BIND_PLAYER====",ok,tostring_r(uid_info_map))
        if not ok or not uid_info_map or not next(uid_info_map) then
            send_to_gateway('activity.RSP_BIND_PLAYER',{result = error_code.ACT_BIND_NOT_PLAYER})
            return
        end
    end

    R().basesvr({key=uid}):send('.msg_handler','set_bind_uid',uid,msg.bind_uid)
    local config = global_configs.award
    local count = msg.bind_uid ~= game_def.NEW_BIND_ACT_SYSTEM_UID and config.bind_add_count or 0
    local info = {bind_add_count = count,bind_uid = msg.bind_uid}
    local ok,free_count = R().exdbsvr(1):call('.award_user_handler','add_free_count',uid,cur_index,info)
    print("add_free_count===========",ok,free_count)
    send_to_gateway('award.RSP_BIND_PLAYER',{bind_uid = msg.bind_uid,free_count = free_count or 0})

    billlog({op="award_bind_player",uid = uid,bind_uid = msg.bind_uid})

    return true
end

--随机一个不中奖的牌
local function rand_noaward_card(card_rate)
    local ret_data = {}
    local card_list = {}
    for _,card_info in pairs(card_rate) do
        if card_info.award_coins <= 0 then
            table_insert(card_list,card_info)
        end
    end

    if #card_list > 0 then
        local index = math_random(1,#card_list)
        ret_data.card_num = card_list[index].card
        ret_data.award_coins = card_list[index].award_coins
    end

    return ret_data
end

local function make_card_id(sign,number)
    return sign * 100 + number
end

local function random_card(store_coins,pay_coins,charge_money,conf)
    local ret_data = {}
    local add_rate = 0
    local random_num = math_random(1, 100)
    for _,card_info in pairs(conf.card_rate) do
        add_rate = add_rate + card_info.rate
        if random_num <= add_rate then
            ret_data.card_num = card_info.card
            ret_data.award_coins = card_info.award_coins
            break
        end
    end

    --万一配置错了,随机不出牌,记录下日志,随机一个不中奖的牌
    if not next(ret_data) then
        errlog("random_card_error")
        ret_data = rand_noaward_card(conf.card_rate)
    end

    --绑定的次数,需要充值达到一定金额才能中奖
    if pay_coins <= 0 and (charge_money or 0) < conf.charge_coins then
        ret_data = rand_noaward_card(conf.card_rate)
        print("use_bind========",pay_money)
    end
    
    --小于警报值,再随机一次不中奖牌
    if store_coins - ret_data.award_coins < conf.store_warn then
        ret_data = rand_noaward_card(conf.card_rate)
    end

    --随机一个牌颜色
    local num = ret_data.card_num
    if num ~= BLACK_JOKER_NUMBER and num ~= RED_JOKER_NUMBER then
        local sign = math_random(1,4)
        ret_data.card_num = make_card_id(sign,num)
    end

    return ret_data
end

local function rand_cp_code(cur_index,pay_coins)
    local mid = string.format("%03d",cur_index)
    local cpcode = math_random(100000,999999)
    local ret_code = "CP" .. mid .. cpcode

    local award_count = player.user_data.award_count 
    if pay_coins <= 0 and award_count <= 0 then --无效的彩票码
        return ret_code,false
    end

    local award = global_configs.award
    if math_random(1,100) <= award.lottery_rate then
        return ret_code,true
    end
end
---------------------------------暂时屏蔽大抽奖------------------------
function award_handler.REQ_LUCKY_DRAW(msg)
    -- local ok,cur_index,code= R().mailsvr(1):call('.award_mgr','get_cur_index')
    -- if not ok or not cur_index then
         send_to_gateway('award.RSP_LUCKY_DRAW',{result = code or -1})
    --     return
    -- end

    -- local uid = player.uid
    -- local ok,base_data = R().basesvr({key=uid}):call('.msg_handler','get_base_data',uid)
    -- if not ok or not base_data then
    --     send_to_gateway('award.RSP_LUCKY_DRAW',{result = -2})
    --     return
    -- end

    -- local ok,store_coins = R().mailsvr(1):call('.award_mgr','get_store_coins',cur_index)
    --  print("REQ_LUCKY_DRAW==============2222222",ok,store_coins)
    -- if not ok or not store_coins then
    --     send_to_gateway('award.RSP_LUCKY_DRAW',{result = -4})
    --     return
    -- end

    -- --扣免費次數,扣錢
    -- local config = global_configs.award
    -- local pay_succ  = false --是否支付成功
    -- local pay_coins = 0 --支付了多少錢
    -- local ok,succ = R().exdbsvr(1):call('.award_user_handler','sub_free_count',uid,cur_index,1)
    -- print("sub_free_count==============",ok,succ)
    -- if ok and succ then
    --     pay_succ = true
    -- end
    -- if not pay_succ then
    --     local cost = config.award_cost
    --     local exinfo = {channel = player.channel,cur_channel = player.cur_channel}
    --     local ok,succ,ret = R().basesvr({key=uid}):call('.msg_handler','reduce_coins',uid,cost,reason.AWARD_LUCKY_DRWA,exinfo)
    --     print("reduce_coins=====================",ok,succ,ret)
    --     if ok and succ and ret then
    --         pay_succ = true
    --         pay_coins = ret.chged
    --         notify_money_changed(uid,{coins = ret.curr})
    --     end
    -- end
    -- if not pay_succ then
    --     send_to_gateway('award.RSP_LUCKY_DRAW',{result = error_code.GOLD_IS_NOT_ENOUGH})
    --     return
    -- end

    -- --增加金币抽奖次数
    -- if pay_coins > 0 then
    --     R().mailsvr(1):send('.award_mgr','add_store_coins',cur_index,pay_coins)
    --     local data = {
    --         bind_uid = base_data.bind_uid,
    --         count = 1,
    --         advert_condition = config.advert_condition,
    --         advert_add_count = config.advert_add_count
    --     }
    --     R().exdbsvr(1):send('.award_user_handler','add_coins_award_count',uid,cur_index,data)
    -- end

    -- --每次抽奖从库存分一部分去奖池和库存
    -- local add_award_coins = math_floor(config.award_cost * (config.award_pool_rate or 0) / 10000)
    -- local add_fee_coins = math_floor(config.award_cost * (config.fee_rate or 0) / 10000)
    -- print("update_coins======================",add_award_coins,add_fee_coins)
    -- R().mailsvr(1):send('.award_mgr','reduce_store_coins',cur_index,add_award_coins+add_fee_coins)
    -- R().mailsvr(1):send('.award_mgr','add_fee_coins',cur_index,add_fee_coins)

    -- local ok,award_pool_coins = R().mailsvr(1):call('.award_mgr','add_award_pool',cur_index,add_award_coins)
    -- print("award_pool_coins=================",ok,award_pool_coins)
    -- if ok and award_pool_coins then
    --     print("111111111111111111")
    --     send_to_gateway('award.NTF_AWARD_POOL_CHANGE',{coins = award_pool_coins})
    -- end

    -- local award_result = random_card(store_coins,pay_coins,base_data.pay_money,config)
    -- award_result.cpcode,award_result.valid = rand_cp_code(cur_index,pay_coins)
    -- print("lucky_draw_result===========",tostring_r(award_result))
    -- R().exdbsvr(1):send('.award_user_handler','update_award_result',uid,cur_index,award_result)
    -- player.user_data.award_count = player.user_data.award_count + 1

    -- billlog({op="award_lucky_draw",uid = uid,pay_coins = pay_coins,cpcode = award_result.cpcode,cp_valid = award_result.valid or false})

    -- send_to_gateway('award.RSP_LUCKY_DRAW',{})

    return true
end

function award_handler.REQ_LUCKY_DRAW_RESULT(msg)
    -- local ok,cur_index,code = R().mailsvr(1):call('.award_mgr','get_cur_index')
    -- if not ok or not cur_index then
         send_to_gateway('award.RSP_LUCKY_DRAW',{result = code or -1})
    --     return
    -- end

    -- local uid = player.uid
    -- local ok,result = R().exdbsvr(1):call('.award_user_handler','get_award_result',uid,cur_index)
    -- print("get_award_result==============",ok,tostring_r(result))
    -- if not ok or not result then
    --     send_to_gateway('award.RSP_LUCKY_DRAW_RESULT',{result = -2})
    --     return 
    -- end

    -- --减库存
    -- if result.award_coins and result.award_coins > 0 then
    --     R().mailsvr(1):send('.award_mgr','reduce_store_coins',cur_index,result.award_coins)
    --     local exinfo = {channel = player.channel,cur_channel = player.cur_channel}
    --     R().basesvr({key=uid}):send('.msg_handler','add_coins',uid,result.award_coins,reason.AWARD_LUCKY_DRWA,exinfo)
    -- end

    -- local rsp = {
    --     card = result.card_num,
    --     coins = result.award_coins,
    --     is_lottery_ticket = result.cpcode and true or false,
    --     is_award = ((result.award_coins or 0) > 0 or result.cpcode) and true or false,
    -- }
    -- send_to_gateway('award.RSP_LUCKY_DRAW_RESULT',rsp)

    return true
end

function award_handler.REQ_ONE_ISSUE_INFO(msg)
    local ok,cur_index,code = R().mailsvr(1):call('.award_mgr','get_cur_index')
    if not ok or not cur_index then
        send_to_gateway('award.RSP_LUCKY_DRAW',{result = code or -1})
        return
    end

    local ok,one_iss_info = R().mailsvr(1):call('.award_mgr','get_one_issue_info',cur_index,msg.issue_num)
    print("REQ_ONE_ISSUE_INFO==============",ok,tostring_r(one_iss_info))
    if not ok or not one_iss_info then
        send_to_gateway('award.RSP_ONE_ISSUE_INFO',{result = -1})
        return
    end

    local issue_result_list = {}
    for k,v in pairs(one_iss_info) do
        local t = {uid = v.uid,award_count = v.award_count,award_coins = v.award_coins,icon = v.icon,name = v.name}
        table_insert(issue_result_list,t)
    end

    --排序
    table_sort(issue_result_list, function(issue1,issue2) return issue1.award_coins > issue2.award_coins end)
    send_to_gateway('award.RSP_ONE_ISSUE_INFO',{issue_result_list = issue_result_list,issue_num = msg.issue_num})

    return true
end

function award_handler.REQ_AWARD_ISSUE_INFO(msg)
    local ok,cur_index,code = R().mailsvr(1):call('.award_mgr','get_cur_index')
    if not ok or not cur_index then
        send_to_gateway('award.RSP_LUCKY_DRAW',{result = code or -1})
        return
    end

    local ok,all_award_issue_info = R().mailsvr(1):call('.award_mgr','get_all_award_issue_info',cur_index)
    print("REQ_AWARD_ISSUE_INFO===========",ok,tostring_r(REQ_AWARD_ISSUE_INFO))
    if not ok or not all_award_issue_info then
        send_to_gateway('award.RSP_AWARD_ISSUE_INFO',{result = -2})
        return
    end

    local issue_list = {}
    for k,v in pairs(all_award_issue_info) do
        local end_time = utils.getWeekZeroTime(v.begin_time,true)
        local t = {issue_num = v.cur_index,begin_time = v.begin_time,end_time = end_time}
        table_insert(issue_list,t)
    end
    send_to_gateway('award.RSP_AWARD_ISSUE_INFO',{issue_list = issue_list})

    return true
end

function award_handler.REQ_PLAYER_LOTTERY_INFO(msg)
    local ok,cur_index,code = R().mailsvr(1):call('.award_mgr','get_cur_index')
    if not ok or not cur_index then
        send_to_gateway('award.RSP_PLAYER_LOTTERY_INFO',{result = code or -1})
        return
    end

    local uid = player.uid
    local ok,result = R().exdbsvr(1):call('.award_user_handler','get_cp_award_log',uid,cur_index)
    print("REQ_PLAYER_LOTTERY_INFO=============",ok,tostring_r(result))
    if not ok or not result then
        send_to_gateway('award.RSP_PLAYER_LOTTERY_INFO',{result = -1})
        return 
    end
    local ok,begin_time = R().mailsvr(1):call('.award_mgr','get_begin_time',cur_index)
    print("REQ_PLAYER_LOTTERY_INFO=============22",ok,begin_time)
    if not ok or not begin_time then
        send_to_gateway('award.RSP_PLAYER_LOTTERY_INFO',{result = -2})
        return
    end

    local end_time = utils.getWeekZeroTime(begin_time,true)
    send_to_gateway('award.RSP_PLAYER_LOTTERY_INFO',{lottery_list = result,audit_result_time = end_time})

    return true
end

function award_handler.REQ_FREE_COUNT_INFO(msg)
    local ok,cur_index,code = R().mailsvr(1):call('.award_mgr','get_cur_index')
    if not ok or not cur_index then
        send_to_gateway('award.RSP_FREE_COUNT_INFO',{result = code or -1})
        return
    end

    local uid = player.uid
    local ok,ret_data = R().exdbsvr(1):call('.award_user_handler','get_free_count_log',uid,cur_index)
    print("REQ_FREE_COUNT_INFO================",ok,tostring_r(ret_data))
    if not ok or not ret_data then
        send_to_gateway('award.RSP_FREE_COUNT_INFO',{free_count_list = {}})
        return
    end
    send_to_gateway('award.RSP_FREE_COUNT_INFO',{free_count_list = ret_data})

    return true
end

function award_handler.REQ_PLAYER_AWARD_INFO(msg)
    local ok,cur_index,code = R().mailsvr(1):call('.award_mgr','get_cur_index')
    if not ok or not cur_index then
        send_to_gateway('award.RSP_PLAYER_AWARD_INFO',{result = code or -2})
        return
    end

    local rules = {}
    local card_list = {}
    local config = global_configs.award
    for k,v in pairs(config.card_rate) do
        table_insert(card_list,{card_num = v.card,award_coins = v.award_coins})
    end
    rules.card_list = card_list
    rules.coin_cost = config.award_cost
    rules.bind_add_count = config.bind_add_count
    rules.award_count = config.advert_condition
    rules.award_free_count = config.advert_add_count
    rules.lottery_award_count = 100

    local uid = player.uid
    local ok,bind_uid = R().basesvr({key=uid}):call('.msg_handler','get_bind_uid',uid)
    print("REQ_PLAYER_AWARD_INFO=====1111111",ok,bind_uid)
    local ok,free_count = R().exdbsvr(1):call('.award_user_handler','get_free_count',uid,cur_index)
    print("REQ_PLAYER_AWARD_INFO=====2222222",ok,free_count)
    local ok,award_pool_coins = R().mailsvr(1):call('.award_mgr','get_award_pool_coins',cur_index)
    print("REQ_PLAYER_AWARD_INFO=====3333333",ok,award_pool_coins)
    local ok,fake_pool_coins = R().mailsvr(1):call('.award_mgr','get_fake_store_coins',cur_index)
    print("REQ_PLAYER_AWARD_INFO=====444444",ok,fake_pool_coins)
    local rsp = {
        bind_uid = bind_uid or 0,
        free_count = free_count or 0,
        award_pool_coins = (award_pool_coins or 0) + (fake_pool_coins or 0),
        rules = rules,
    }
    send_to_gateway('award.RSP_PLAYER_AWARD_INFO',rsp)

    return true
end

function award_handler.REQ_AWARD_ICON_STATUS(msg)
    local config = global_configs.award
    if not config then
        send_to_gateway('award.RSP_AWARD_ICON_STATUS',{result = -1})
        return
    end
    send_to_gateway('award.RSP_AWARD_ICON_STATUS',{open = config.open})

    return true
end

function award_handler.REQ_AWARD_POOL_COINS(msg)
    local ok,cur_index,code = R().mailsvr(1):call('.award_mgr','get_cur_index')
    if not ok or not cur_index then
        send_to_gateway('award.RSP_AWARD_ICON_STATUS',{result = -1})
        return
    end
    local ok,award_pool_coins = R().mailsvr(1):call('.award_mgr','get_award_pool_coins',cur_index)
    local ok,fake_pool_coins = R().mailsvr(1):call('.award_mgr','get_fake_store_coins',cur_index)
    if not ok or not award_pool_coins or not fake_pool_coins then
        send_to_gateway('award.RSP_AWARD_ICON_STATUS',{result = -2})
        return
    end
    send_to_gateway('award.RSP_AWARD_POOL_COINS',{coins = award_pool_coins + fake_pool_coins})

    return true
end

--------------------------------------------------------
handler.register_module_handlers('award',award_handler)

